﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;
using zijian666.SuperConvert.Core;
using zijian666.SuperConvert.Interface;

namespace zijian666.SuperConvert.Json
{
    public class JsonElementTranslator : JsonConverter<object>, ITranslator
    {
        public bool CanTranslate(Type type) => type == typeof(JsonElement);
        public object Translate(IConvertContext context, object input)
        {
            var conv = context.Settings.GetConvertor<DynamicObject>(context);
            return Translate(context, conv, input);
        }

        public object Translate(IConvertContext context, IConvertor<DynamicObject> convertor, object input)
        {
            var element = (JsonElement)input;
            switch (element.ValueKind)
            {

                case JsonValueKind.Array:
                    var list = new ArrayList();
                    foreach (var item in element.EnumerateArray())
                    {
                        list.Add(Translate(context, convertor, item));
                    }
                    return Dynamic(context, convertor, list.ToArray());
                case JsonValueKind.Object:
                    var expando = new Dictionary<string, object>();
                    foreach (var item in element.EnumerateObject())
                    {
                        expando.Add(item.Name, Translate(context, convertor, item.Value));
                    }
                    return Dynamic(context, convertor, expando);
                case JsonValueKind.String:
                    return Dynamic(context, convertor, element.GetString());
                case JsonValueKind.Number:
                    return Dynamic(context, convertor, element.GetDecimal());
                case JsonValueKind.True:
                    return Dynamic(context, convertor, true);
                case JsonValueKind.False:
                    return Dynamic(context, convertor, false);
                case JsonValueKind.Null:
                case JsonValueKind.Undefined:
                    return Dynamic(context, convertor, DBNull.Value);
                default:
                    return Dynamic(context, convertor, null);
            }
        }

        public object Dynamic(IConvertContext context, IConvertor<DynamicObject> convertor, object value)
        {
            if (convertor != null)
            {
                var result = convertor.Convert(context, value);
                if (result.Success)
                {
                    return result.Value;
                }
            }
            return value;
        }

        public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var element = JsonSerializer.Deserialize<JsonElement>(ref reader, options);
            return Translate(ConvertContext.Current ?? new ConvertContext(), element);
        }

        public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
        {
            throw new NotImplementedException();
        }
    }
}
